package id.mankel.commons.mybatis;

import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class ExecutorUpdatePlugin implements Interceptor {

    static final String KEY_PROPERTY = "keyProperty";
    static final String KEY_PROPERTY_HOLDER = "${keyProperty}";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        if (SqlCommandType.INSERT.equals(ms.getSqlCommandType()) && ms.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
            MapperMethod.ParamMap<String> paramMap = (MapperMethod.ParamMap) args[1];
            String[] keyProperties = ms.getKeyProperties();
            for (int i = 0; i < keyProperties.length; i++) {
                if (keyProperties[i].contains(KEY_PROPERTY_HOLDER)) {
                    keyProperties[i] = keyProperties[i].replace(KEY_PROPERTY_HOLDER, paramMap.get(KEY_PROPERTY));
                    break;
                }
            }
        }
        Object ret = invocation.proceed();
        return ret;
    }

}
